package org.mayanjun.code.easyweb.springmvc.config;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import org.springframework.web.filter.CharacterEncodingFilter;
import org.springframework.web.filter.HiddenHttpMethodFilter;
import org.springframework.web.filter.HttpPutFormContentFilter;
import org.springframework.web.servlet.DispatcherServlet;
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;

import javax.servlet.Filter;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRegistration;
import java.util.Collection;
import java.util.Map;

/**
 * The web application initialize implementation based on the SPI in Servlet3.0+ specification
 * 
 * @author mayanjun
 */
public class ApplicationInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
	
	private static final Logger LOG = LoggerFactory.getLogger(ApplicationInitializer.class);

	@Override
	public void onStartup(ServletContext servletContext) throws ServletException {
		int majorVersion = servletContext.getMajorVersion();
		int minorVersion = servletContext.getMinorVersion();
		LOG.info("Container servlet version: {}.{}", majorVersion, minorVersion);

		int eMajorVersion = servletContext.getEffectiveMajorVersion();
		int eMinorVersion = servletContext.getEffectiveMinorVersion();
		LOG.info("App servlet version: {}.{}", eMajorVersion, eMinorVersion);

		Map<String, ? extends ServletRegistration> regs = servletContext.getServletRegistrations();
		if(regs != null && !regs.isEmpty()) {
			Collection<? extends ServletRegistration> coll = regs.values();
			for(ServletRegistration reg : coll) {
				String cn = reg.getClassName();
				if(DispatcherServlet.class.getCanonicalName().equals(cn)) {
					LOG.info("DispatcherServlet is already registered in web.xml");
					return;
				}
			}
		}
		super.onStartup(servletContext);
	}

	@Override
	protected String[] getServletMappings() {
		return new String[] {"/"};
	}

	/**
	 * Note that this is a convenient way to add Filter instances and have them
	 * automatically mapped to the ServletDispatcher
	 */
	@Override
	protected Filter[] getServletFilters() {
		CharacterEncodingFilter f1 = new CharacterEncodingFilter();
		f1.setEncoding("utf-8");
		f1.setForceEncoding(true);

		//MultipartFilter f2 = new MultipartFilter();
		//f2.setMultipartResolverBeanName("multipartResolver");

		HttpPutFormContentFilter f2 = new HttpPutFormContentFilter();

		HiddenHttpMethodFilter f3 = new HiddenHttpMethodFilter();

		LOG.info("Adding filter to dispatcher servlet[CharacterEncodingFilter,HiddenHttpMethodFilter,HttpPutFormContentFilter]");

		return new Filter[]{f1,f2,f3};
	}

	@Override
	protected WebApplicationContext createRootApplicationContext() {
		AnnotationConfigWebApplicationContext ctx = (AnnotationConfigWebApplicationContext)super.createRootApplicationContext();
		if(ctx != null) {
			ctx.setDisplayName("WebMvcApplicationConfig(Root)");
		}
		return ctx;
	}

	@Override
	protected WebApplicationContext createServletApplicationContext() {
		AnnotationConfigWebApplicationContext ctx =  (AnnotationConfigWebApplicationContext)super.createServletApplicationContext();
		if(ctx != null) {
			ctx.setDisplayName("ServletApplicationConfig(DispatcherServlet)");
		}
		return ctx;
	}

	@Override
	protected Class<?>[] getRootConfigClasses() {
		return new Class<?>[] {WebMvcApplicationConfig.class};
	}

	@Override
	protected Class<?>[] getServletConfigClasses() {
		return new Class<?>[]{ServletApplicationConfig.class};
	}
}
